<?php
/*
 cache.php by martin $ 2009/04/16 01:18:33
  ｜予め「Recently」「Recent Comments」「Recent TrackBack」「Category」「Archives」のエントリーや
  ｜数をシリアル化してcache.dbファイルに保存して，ページ作成時には，ここから読み取る。
  ｜各月の記事数もキャッシュに(ver.1.5～)。 
*/

mk_fl($cache_file = PATH.'cache/cache.db');

if(is_file($cache_file)){
 $_cache = unserialize(get_file_content($cache_file));
}

if(empty($_cache)){
 update_cache(array('recently', 'recent_comments', 'recent_trackbacks', 'category', 'articles_volume', 'pages', 'tags'));
} else return;

function make_cache($TAR=array(), $newName=''){
 global $CATEGORY_LIST, $PAGES_LIST, $_cache;
 // $TAR = array('recently', 'recent_comments', 'recent_trackbacks', 'category', 'articles_volume', 'pages', 'tags');
 if(empty($TAR)) $TAR = array('recently', 'recent_comments', 'recent_trackbacks', 'category', 'articles_volume', 'pages', 'tags');
 include_once (OD.'category.ini.php');
 $LOGS = my_glob(EXT, LOG);
 usort($LOGS, 'SORT_BY_DATE');
 rewrite(PATH.DB.'log.db', str_replace(PATH, '', $LOGS)); // log.dbの更新

 foreach($LOGS as $log){ // 空のログは削除
  $c = get_file_content($log);
  if(empty($c) || filesize($log)==0){
   if(is_file($log)){
    unlink($log);
    $LOGS = my_glob(EXT, LOG);
    usort($LOGS, 'SORT_BY_DATE');
    rewrite(PATH.DB.'log.db', str_replace(PATH, '', $LOGS)); // log.dbの更新
   }
  }
 }
 unset($c);
 if(in_array('recently', $TAR)){
  $_cache['recently'] = array();

  if(count($LOGS) > 0){
   $_lines = array();
   $countLOGS = count($LOGS);
   for($j=0; $j < $countLOGS; $j++){
    $lines = my_file($LOGS[$j]);
    $_lines = array_merge($_lines, $lines);
    if(count($_lines) > RECENT_ENTRIES) break;
   }
  }
  if(!empty($_lines)) $LINES = array_slice($_lines, 0, RECENT_ENTRIES);
  if(!empty($LINES)){
   foreach($LINES as $line){
    list($id,,$title,) = explode('|', $line);
    if(strpos($title, ',')){
     list($title, $pm_title) = explode(',', $title);
     if(MODE_STATIC){
      $title = $title.','.date('Ym', str_replace('d', '', $id)).'-'.$pm_title.EXT_STATIC;
     } else $title = $title.',index.php?UID='.$id;
    } else $title = MODE_STATIC ? $title.','.$id.EXT_STATIC : $title.',index.php?UID='.$id;
    $_cache['recently'][$id] = $title;
   }
  }
 }
 unset($_lines, $LINES);
 if(in_array('articles_volume', $TAR)){
  $articles_volume = $_cache['articles_volume'] = $_cache['total_articles_count'] = array();
  foreach($LOGS as $log){
   if(!is_file($log)) continue;
   list($real, $nominal) = my_file($log, -1); # return array
   $articles_volume[basename($log, EXT)] = array(count($real), count($nominal)); // real, nominal
  }
  unset($real, $nominal);
  $_cache['articles_volume'] = $articles_volume;
  
  if(isset($_cache['articles_volume'])){
   $totalCount = array('real'=>0, 'nominal'=>0);
   foreach($_cache['articles_volume'] as $c){
    $totalCount['real'] += (int)$c[0];
    $totalCount['nominal'] += (int)$c[1];
   }
   $_cache['total_articles_count'] = $totalCount;
  }
 }
 unset($LOGS);

 if(in_array('recent_trackbacks', $TAR)){
  $TB_FILES = my_glob(EXT, TB_DIR);
  $_cache['recent_trackbacks'] = $tbs = $tbs_concat = array();
  if(empty($TB_FILES)){
   $_cache['recent_trackbacks'] = array();
  } else {
   foreach ($TB_FILES as $tbf){
    if(filesize($tbf)==0) unlink(PATH.$tbf);
    if(preg_match("/(\d{9,})/", $tbf, $mt)){
     $tb_contents = unserialize( get_file_content($tbf) );
     $target_log = log_($mt[1]);
     $reg = preg_grep("/^$mt[1]\|/", my_file($target_log));
     $pm_title = $_title = '';
     if($reg=array_shift($reg)){
      list(,,$title,) = explode('|', $reg);
      if(strpos($title, ',')) list($title, $pm_title) = explode(',', $title);
      if(MODE_STATIC) $pm_title = empty($pm_title) ? $mt[1] : date('Ym', $mt[1]).'-'.$pm_title.EXT_STATIC;
      $_title = my_substr($title, 0, 18);
      if(count($tb_contents)>0){
       $tbs[$mt[1]][0] = count($tb_contents).'|'.$_title.'|'.$title.','.$pm_title;
      }
     }
     foreach ($tb_contents as $i=>$tbc){
      $blog_name = !empty($tbc['blog_name']) ? rawurldecode($tbc['blog_name']) : rawurldecode($tbc['url']);
      $blog_name = MAGIC_QUOTES ? stripslashes($blog_name) : $blog_name;
      $blog_name = my_substr($blog_name, 0,18);
      if(isset($tbs[$mt[1]][0])) $tbs[$mt[1]][$i+1] = $tbc['entry'].'|'.$blog_name;
     }
    }
   }
   foreach($tbs as $uid=>$entries){
    foreach($entries as $i=>$entry){
     if($i==0) continue;
     $tbs_concat[] = $entry.'$'.$uid.'$'.$entries[0];
    }
   }
   usort($tbs_concat, 'SORT_BY_DATE');
   array_splice($tbs_concat, 2 * RECENT_TRACKBACKS);
   $tbs = array();
   foreach($tbs_concat as $i => $tb){
    if(count($tbs) == RECENT_TRACKBACKS) break;
    list($entry, $uid, $index) = explode('$', $tb);
    $tbs[$uid][0] = $index;
    $tbs[$uid][] = $entry;
   }
   unset($TB_FILES);
   $_cache['recent_trackbacks'] = $tbs;
  }
 }
 unset($tbs_concat, $tb_contents);

 if(in_array('category', $TAR)){
  $_cache['category'] = array();
  foreach ($CATEGORY_LIST as $line){
   list($_cat,) = explode('|', $line, 2);
   if(strpos($_cat, "\t")) list($_cat, $catlink) = explode("\t", $_cat);
   $_articles = get_articles_by_category($_cat);
   $nominal = 0;
   foreach ($_articles as $a){
    if(preg_match('/^\d+?d\|/', $a)) $nominal++;
   }
   $_articlesNum = count($_articles);
   $_cache['category'][$_cat."\t".$catlink] = (int)($_articlesNum - $nominal)."|".$_articlesNum;
  } #foreach
 }

 if(in_array('pages', $TAR)){
  $_cache['pages'] = array();
  include OD.'pages.ini.php';
  if(!empty($PAGES_LIST)){
   foreach ($PAGES_LIST as $page){
    list(, $lastmod, $name, $fname, $ontop) = explode('|', $page);
    $_cache['pages'][$lastmod] = $name.'|'.$fname.'|'.$ontop;
   }
  }
 }
 
 if(in_array('tags', $TAR)){
  $_cache['tags'] = array();
  include OD.'tags.ini.php';
  $ORG_LIST = $TAGS_LIST;
  foreach ($TAGS_LIST as $i=>$tag){
   $draft = 0;
   $_tag = explode('|', $tag);
   $ents = explode(',', $_tag[1]);
   $entries = sizeof($ents);
   foreach ($ents as $ent){
    if(strpos($ent, 'd')) $draft++;
    $log = log_($ent);
    if($log==''){ $entries--; continue; }
    $line = preg_grep("/$ent/", file($log));
    if(empty($line)){
     $TAGS_LIST = preg_replace("/(,?)$ent/", '\\1', $TAGS_LIST);
     $entries--;
    }
   }
   $fontsize = ($fontsize = (int)(TAG_MIN_FONT_SIZE + $entries)) > TAG_MAX_FONT_SIZE ? TAG_MAX_FONT_SIZE : $fontsize - 1;
   if($entries > 0) $_cache['tags'][$_tag[0]] = array((int)($entries - $draft)."|$entries", $fontsize); // count, font-size
  }
  if($ORG_LIST != $TAGS_LIST){
   $_TAGS_LIST = array();
   foreach ($TAGS_LIST as $ent){
    list($t, $ids) = explode('|', $ent);
    if(empty($ids)) continue;
    $_TAGS_LIST[] = $ent;
   }
   if(!empty($_TAGS_LIST))rewrite_ini(OD.'tags.ini.php', $_TAGS_LIST);
  }
 }
 unset($CATEGORY_LIST, $PAGES_LIST, $TAGS_LIST, $_TAGS_LIST);
 
 if(in_array('recent_comments', $TAR)){
  $_cache['recent_comments'] = array();
  $_cache['recent_comments'] = get_recent_comments(RECENT_COMMENTS, $newName);
 }
 return $_cache;
}

function update_cache($target = array(), $id='', $newName=''){
 if($id != ''){
  $Ym = date('Ym', substr($id,0,10));
  if(is_file($c=PATH.DB.$Ym.'_box1.db')) unlink($c);
  if(is_file($c=PATH.DB.$Ym.'_box2.db')) unlink($c);
  if(is_file($c=PATH.DB.$Ym.'_line1.db')) unlink($c);
  if(is_file($c=PATH.DB.$Ym.'_line2.db')) unlink($c);
 }
 $cache = make_cache($target, $newName);
 if(!empty($cache)){
  rewrite(PATH.'cache/cache.db', $cache = serialize($cache));
  unset($cache);
 }
 return TRUE;
}

function get_recent_comments($limit=RECENT_COMMENTS, $newName=ONAME){ /* 最近のコメントの取得(新しい順かつコメント順に) */
 $LOGS = my_glob(EXT, CMT_DIR);
 $comments = array();
 foreach ($LOGS as $log){
  $lines = file($log);
  $src = array_shift($lines);
  if(count($lines) == 0){
   @unlink(PATH.$log);
   continue;
  }
  list($uid,,$title) = explode('|', $src);
  if(strpos($title, ',')) list($title,) = explode(',', $title);
  $lines = preg_replace('{^(\d{9,})\|(.+?)\|.+\|([01])\|$}e', "'$1|$2'.('$3'==1?'$':NL)", $lines);
  $lines = preg_replace('{\s}', '', $lines);
  $_lines = array();
  foreach ($lines as $j=>$l){
   list($d, $name) = explode('|', $l);
   if(strpos($name, '$')) continue; // Nondisclosure
   if($name==ONAME||isRegisteredUser($name)|| $newName==$name){
    $_lines[] = "$d|'$name"; // オーナー・共有ユーザにマーク
   } else $_lines[] = $l;
  }
  if(count($_lines) > (ENTRY_BOX * 2 + 1)){
   list($ini, ) = explode('|', $_lines[0]);
   $_lines = array_slice($_lines, -(ENTRY_BOX * 2 + 1));
   $_lines[0] = $ini.'|$$'; # set $$ as mark
  }
  if(empty($_lines)) continue;
  $comments[] = trim(max($_lines))."|$uid|".trim($title).'|'.implode("\t", $_lines);
 }
 usort($comments, 'SORT_BY_DATE');
 $comments = array_slice($comments, 0, $limit);
 $comments = preg_replace('{^\d{9,}\|.+?\|(\d{9,}\|.+?)\|(.+$)}', "$1\t$2", $comments);
 unset($lines, $_lines);
 return $comments;
}

?>
